package com.erp.gather.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.erp.gather.config.UrlConfig;
import com.erp.gather.domain.ErpCollectProductOptimize;
import com.ruoyi.gather.api.domain.ErpProductAtlas;
import com.erp.gather.domain.ErpSellerReplaceImageRecord;
import com.erp.gather.mapper.*;
import com.erp.gather.service.IAeUploadOssService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.ImageMergeUtils;
import com.ruoyi.gather.api.domain.ErpCollectProduct;
import com.ruoyi.gather.api.domain.ErpCollectProductSku;
import com.ruoyi.system.api.RemoteFileService;
import com.ruoyi.system.api.domain.SysOss;
import com.ruoyi.system.api.domain.dto.OssUrlDto;
import com.ruoyi.system.api.domain.vo.SysOssVo;
import lombok.RequiredArgsConstructor;
import org.apache.http.entity.ContentType;
import org.apache.logging.log4j.util.Strings;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class AeUploadOssServiceImpl implements IAeUploadOssService {
    private final ErpCollectProductOptimizeMapper collectProductOptimizeMapper;
    private final ErpSellerReplaceImageRecordMapper sellerReplaceImageRecordMapper;
    private final ErpCollectProductSkuMapper erpCollectProductSkuMapper;
    private final ErpCollectProductMapper erpCollectProductMapper;
    private final ErpProductAtlasMapper erpProductAtlasMapper;

    @Resource
    UrlConfig urlConfig;

    @Resource
    RemoteFileService remoteFileService;

    /**
     * 图片组合
     *
     * @param oldPicUrls
     * @param sellerId
     * @param collectProductId
     * @return
     */
    @Override
    public String imageMerge(String oldPicUrls, Long sellerId, Long collectProductId) {
        List<ErpSellerReplaceImageRecord> replaceList = new ArrayList<>();
        ErpSellerReplaceImageRecord sellerReplaceImageRecord = null;
        /**
         * 合成图片处理流程 1、根据传入的原始图片，进行图片分割 2、根据单一图片，获取对应的多张元素图片和对应的背景图标签
         * 3、分割元素图，并随机一张图片（当前默认选择第一张，后期再修改） 4、根据对应的背景图标签，获取该标签下的所有图片地址
         * 5、随机挑选一张背景图，并进行合并处理 6、将临时图片上传至oss并覆盖原图片 7、删除临时图片
         */
        // 元素图
        String elementPic = "";
        // 背景图
        String backgroundPic = "";
        // 新图地址集合
        String newPicUrls = "";
        ErpCollectProductOptimize collectProductOptimize = null;
        // 1、轮播图
        if (oldPicUrls != null && !oldPicUrls.trim().equals("")) {
            // 1、将传入图片进行分割
            String picUrl[] = oldPicUrls.split(";");

//			ExecutorService executorService = Executors.newFixedThreadPool(10);
//			ArrayList<Future<List<String>>> list = new ArrayList<>();
            try {
                for (String url : picUrl) {
                    sellerReplaceImageRecord = new ErpSellerReplaceImageRecord();
                    // 2、获取该图片对应的元素图和背景图标签集合
                    try {
                        collectProductOptimize = collectProductOptimizeMapper.queryByOptimizePic(url, collectProductId);
                        if (collectProductOptimize == null || collectProductOptimize.getPics() == null
                                || collectProductOptimize.getPics().equals("")
                                || collectProductOptimize.getTagIds() == null
                                || collectProductOptimize.getTagIds().equals("")) {
                            // 如果没有适合合并的图片，需要把原来的图片继续存到集合里
                            newPicUrls = newPicUrls + ";" + url;
                            continue;
                        } else {
                            // 3、暂时获取第一张元素图
                            elementPic = getOssUrlHeader() + "/" + collectProductOptimize.getPics().split(";")[0];
                            // 4、根据标签随机获取一张背景图
                            backgroundPic = getOssUrlHeader() + "/"
                                    + getBackgroundPic(collectProductOptimize.getTagIds(),
                                    collectProductOptimize.getType().intValue() == 2 ? 1
                                            : collectProductOptimize.getType().intValue());
                        }
                        // 根据元素图和背景图，合并图片 url.substring(url.lastIndexOf("/")+1
//					String newPicUrl = tempPicPath + "" + url.replaceAll("/", "_");
                        String newPicUrl = urlConfig.getTempPicPath() + "" + IdUtil.fastSimpleUUID() + ".jpg";
                        try {
                            ImageMergeUtils.overlyingImageTest(backgroundPic, elementPic, newPicUrl);
                            // 6、将临时图片上传OSS并获取到最新路径并删除临时图片
                            String mergeUrl = uploadNewPicToOss(newPicUrl);
                            newPicUrls = newPicUrls + ";" + mergeUrl;

                            // 7、插入记录
                            sellerReplaceImageRecord.setCollectProductId(collectProductId);
                            sellerReplaceImageRecord.setSellerId(sellerId);
                            sellerReplaceImageRecord.setOldUrl(url);
                            sellerReplaceImageRecord.setNewUrl(mergeUrl);
                            sellerReplaceImageRecord.setTransparentUrl(collectProductOptimize.getPics().split(";")[0]);
                            replaceList.add(sellerReplaceImageRecord);
                        } catch (Exception e) {
                            System.out.println("*****************backgroundPic=" + backgroundPic);
                            System.out.println("*****************elementPic=" + elementPic);
                            // 合并失败后，保留原图链接
                            newPicUrls = newPicUrls + ";" + url;
                        }
                    } catch (Exception e) {
                        System.out.println("*****************backgroundPic=" + backgroundPic);
                        System.out.println("*****************elementPic=" + elementPic);
                        // 合并失败后，保留原图链接
                        newPicUrls = newPicUrls + ";" + url;
                    }

//					Callable<List<String>> callable1 = () -> overlyingImage(url, sellerId, collectProductId,
//							replaceList);
////					FutureTask<String> task1 = new FutureTask<>(callable1);
//					Future<List<String>> submit = executorService.submit(callable1);
//					list.add(submit);
                }
//				for (Future<List<String>> future : list) {
//					List<String> resList = future.get();
//					if (resList.size() > 1) {
//						oldPicUrls = oldPicUrls.replace(resList.get(0), resList.get(1));
//					}
//				}
            } catch (Exception e) {
            }
            sellerReplaceImageRecordMapper.insertBatch(replaceList);
            return newPicUrls.substring(1);
        }
        return oldPicUrls;
    }

    /**
     * 获取oss开头路径
     *
     * @return
     */
    @Override
    public String getOssUrlHeader() {
        R<Object> ossUrlHeader = remoteFileService.getOssUrlHeader();
        if (ossUrlHeader.getCode() != 200) {
            return "获取oss信息失败";
        }
        return ossUrlHeader.getData().toString();
    }

    /**
     * 根据标签获取背景图，路径必然为oss相对路径
     *
     * @param tagIds
     * @return
     */
    @Override
    public String getBackgroundPic(String tagIds, Integer type) {
        if (type.intValue() == 3) {
            // 白底图
            return "common-product/2023/04/25/A3A9697071CE415794AD88EA8192C309.jpg";
        }
        List<Long> idList = Arrays.stream(tagIds.split(",")).map(s -> Long.parseLong(s.trim()))
                .collect(Collectors.toList());
        Long[] ids = idList.toArray(new Long[idList.size()]);
        List<ErpProductAtlas> productAtlasList = erpProductAtlasMapper.getBackgroundPicList(ids, type);
        int atlasCount = productAtlasList.size();
        if (atlasCount < 1) {
            return "";
        }
        Random rand = new Random();
        int bgNum = rand.nextInt(atlasCount - 1);
        return productAtlasList.get(bgNum).getPictureUrl();
    }

    /**
     * 采集库批量上传Oss图片
     */
    @Override
    public Boolean updateProductUrl(ErpCollectProduct collectProduct) {
        LambdaUpdateWrapper<ErpCollectProduct> luw = Wrappers.lambdaUpdate();
        luw.set(ErpCollectProduct::getMarketing, urlsToOssUrls(collectProduct.getMarketing()));
        luw.set(ErpCollectProduct::getImageURLs, urlsToOssUrls(collectProduct.getImageURLs()));
        luw.set(ErpCollectProduct::getWhite, urlsToOssUrls(collectProduct.getWhite()));
        luw.set(ErpCollectProduct::getDetailImg, urlsToOssUrls(collectProduct.getDetailImg()));
        luw.eq(ErpCollectProduct::getId, collectProduct.getId());
        erpCollectProductMapper.update(null, luw);

        List<ErpCollectProductSku> erpCollectProductSkus = erpCollectProductSkuMapper
                .selectList(Wrappers.lambdaQuery(new ErpCollectProductSku())
                        .eq(ErpCollectProductSku::getCollectProductId, collectProduct.getId()));
        erpCollectProductSkus.forEach(erpCollectProductSku -> {
            erpCollectProductSku.setSkuImage(urlsToOssUrls(erpCollectProductSku.getSkuImage()));
            erpCollectProductSkuMapper.updateById(erpCollectProductSku);
        });
        return true;
    }

    /**
     * 上传图片至oss
     */
    @Override
    public String urlsToOssUrls(String urls) {
        if (Strings.isBlank(urls)) {
            return urls;
        }
        String[] urlArr = urls.split(";");
        List<String> urlList = new ArrayList<>();
        for (String url : urlArr) {
            if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("temp-product")) {
                if (url.contains("?")) {
                    url = url.substring(0, url.lastIndexOf("?"));
                }
                if (url.startsWith("temp-product")) {
                    url = "https:/file.pbb2c.com/" + url;
                }
                OssUrlDto ossUrlDto = new OssUrlDto();
                ossUrlDto.setOldUrl(url);
                R<Object> returnObj = remoteFileService.uploadUrl(ossUrlDto);
                if (returnObj.getCode() != 200) {
                    urlList.add(url);
                }else {
                    String toJSONString = JSONObject.toJSONString(returnObj.getData());
                    SysOss sysOssVo = JSONObject.parseObject(toJSONString, SysOss.class);
                    urlList.add(sysOssVo == null ? url : sysOssVo.getUrl());
                }
            } else {
                urlList.add(url);
            }
        }
        return String.join(";", urlList);
    }


    /**
     * 根据图片地址，上传图片
     *
     * @param newPicUrl
     * @return
     */
    @Override
    public String uploadNewPicToOss(String newPicUrl) {
        //TODO 内部类调用

        File file = new File(newPicUrl);
        String name = file.getName();
        InputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        MultipartFile multipartFile = null;
        try {
            multipartFile = new MockMultipartFile(name, name, ContentType.APPLICATION_OCTET_STREAM.toString(),
                    fileInputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        R<Object> fileR = remoteFileService.uploadOss(multipartFile);
        String fileRString = JSONObject.toJSONString(fileR.getData());
        SysOssVo upload = JSONObject.parseObject(fileRString, SysOssVo.class);
        // 删除临时图片
        file.delete();
        return upload.getFileName();
    }

}
